/**
 * 动态创建表单
 * 
 * 说明：
 * 本模块根据后端数据生成相应的表单
 * 
 * 注意：
 * 数据遵循需要指定的格式，不然会出错
 * 所有的css样式基于宽度750px的设计稿编写，并且引用了rpx转换工具
 * 
 * @author 谢敏杰
 */

var data //表单属性数据
var isSend = false  //是否已提交，避免重复发
var imgNum = 0 //图片的数量（包括已经删除的），为图片生成id用
/**
 * 取前一个页面传过来的param
 * @param {*} name 
 * @returns 
 */
function getParam(name) {
    var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
    var r = window.location.search.substr(1).match(reg);
    // console.log(window.location.search.substr(1).match(reg))
    if (r != null) return unescape(r[2]);
    return null;
}

/**
 * 获取数据
 */
function getData() {

    title = getParam('title')

    $.ajax({
        cache: true,
        type: 'get',
        url: `./js/${title}.json`,
        async: false,
        dataType: "json",
        error: function (err) {
            showMessage('请求失败', 'error');
        },
        success: (res) => {
            data = res.data
            console.log('请求成功', res)
        }
    });
}

/**
 * 初始化
 */
function init() {
    getParam()
    //设置页面标题
    getData()
    // console.log(data.title)
    document.title = data.title
    createForm()
}


/**
 * 创建form表单
 */
function createForm() {
    let container = document.getElementById('container')
    let form = document.createElement('form')
    form.setAttribute("enctype", "multipart/form-data")
    form.setAttribute('id', 'form')
    // form.action = url
    // form.method = method
    container.appendChild(form)

    if (data.form) {
        data.form.forEach((item) => {
            switch (item.formType) {
                case 'BasicInput':
                    createBasicInput(item.label, item.attribute, item.placeholder, item.isRequired)
                    break;
                case 'Select':
                    createSelect(item.label, item.attribute, item.selectArr, item.isRequired)
                    break;
                case 'TextArea':
                    createTextArea(item.label, item.attribute, item.placeholder, item.isRequired)
                    break;
                case 'FileInput':
                    createFileInput(item.label, item.attribute, item.maxNum, item.isRequired)
                    break;
                case 'RadioInput':
                    createRdaioInput(item.label, item.attribute, item.selectArr, item.isRequired)
                    break;
                case 'ImageInput':
                    createImageInput(item.label, item.attribute, item.maxNum, item.isRequired)
                    break;
                default:
                    showMessage(item.label + '的表单类型错误!', 'error')
                    break;
            }
        })
        createSubmit('提交')
    } else {
        showMessage('没有获取到数据', 'error')
    }
}

/**
 * 改变样式
 * @param {Array} addStyle //增加样式数组对象
 * @param {Array} removeStyle //清除样式数组对象
 */
function changeClass(addStyle, removeStyle) {
    if (addStyle) {
        addStyle.forEach(element => {
            document.getElementById(element.id).classList.add(element.class)
        });
    }
    if (removeStyle) {
        removeStyle.forEach(element => {
            document.getElementById(element.id).classList.remove(element.class)
        });
    }
}


/**
 * 检查表单
 */
function checkForm() {

    if (!isSend) {
        let flag = true
        var formData = new FormData();
        data.form.forEach(item => {
            if (item.isRequired && flag) {
                if (item.formType == 'Select') {
                    let obj = document.getElementById('selectText' + item.attribute)
                    if (obj.value == "" || obj.value == null) {
                        console.log(item.label + '不能为空！')
                        showMessage(item.label + '不能为空！', 'warning')
                        flag = false
                        return
                    }
                } else if (item.formType == 'RadioInput') {
                    let obj = document.getElementsByName(item.attribute)
                    let checked = false;
                    obj.forEach((element) => {
                        if (element.checked) {
                            checked = true
                        }
                    })
                    if (!checked) {
                        console.log(item.label + '不能为空！')
                        showMessage(item.label + '不能为空！', 'warning')
                        flag = false
                        return
                    }
                } else {
                    let obj = document.getElementById(item.attribute);
                    if (obj.value == "" || obj.value == null) {
                        console.log(item.label + '不能为空！')
                        showMessage(item.label + '不能为空！', 'warning')
                        flag = false
                        return
                    }
                }
            }
        })

        //将数据保存到formData
        data.form.forEach(item => {
            if (item.formType == 'Select') {
                let obj = document.getElementById('selectText' + item.attribute)
                formData.append(item.attribute, obj.value)
            }
            else if (item.formType == 'RadioInput') {
                let obj = document.getElementsByName(item.attribute)
                obj.forEach((element) => {
                    if (element.checked) {
                        console.log(item.attributes, element.value)
                        formData.append(item.attribute, element.value)
                    }
                })
            } else if (item.formType == 'FileInput') {
                let obj = document.getElementById(item.attribute);
                for (let i = 0; i < obj.files.length; i++) {
                    formData.append('file', obj.files[i])
                }
            } else if (item.formType == 'RadioInput') {
                let obj = document.getElementById(item.attribute)
                obj.forEach((element) => {
                    if (element.checked) {
                        formData.append(item.attribute, element.value)
                    }
                })
            } else if (item.formType == 'ImageInput') {
                let obj = document.getElementById('input-' + item.attribute);
                console.log(obj)
                // var imgList = document.getElementsByName('preview-img-' + item.attribute);
                // imgList.forEach((img) => {
                //     let file = img.src;
                //     var type = "image/png";
                //     let conversions = base64ToBlob(file, type);
                //     console.log(conversions)
                //     formData.append('file', conversions)
                // })
                for (let i = 0; i < obj.files.length; i++) {
                    formData.append('image', obj.files[i])
                }
            }
            else {
                let obj = document.getElementById(item.attribute);
                formData.append(item.attribute, obj.value)
            }
        })
        formData.append('title', data.title)

        //提交
        if (flag) {
            $.ajax({
                cache: false,
                type: 'post',
                url: `https://localhost:8081/api/client/apply`,
                async: true,
                // dataType: "json",
                contentType: false,
                processData: false,
                data: formData,
                error: function (err) {
                    showMessage('请求失败', 'error');
                },
                success: (res) => {
                    if (res.code != 200) {
                        showMessage('发送了错误,' + res.msg, 'error')
                    } else {
                        isSend = true
                        showMessage('提交成功！', 'success')
                        location.href = './result.html'
                    }
                }
            });
        }
    } else {
        showMessage('请不要重复提交哦', 'error')
    }
}

/**
 * 创建基本的输入框
 * @param {string} title //标题
 * @param {string} attribute //属性名
 * @param {boolean} isRequired //是否为必填项
 */
function createBasicInput(title, attribute, placeholder, isRequired) {
    let form = document.getElementById('form')
    let wrap = document.createElement('div')
    wrap.classList.add('form-item-base')

    //标题
    let label = document.createElement('label')
    label.classList.add('label')
    if (isRequired) label.classList.add('required')
    label.setAttribute('for', attribute)
    let labelText = document.createTextNode(title)
    label.appendChild(labelText)

    wrap.appendChild(label)

    let input = document.createElement('input')
    input.setAttribute('name', attribute)
    input.setAttribute('id', attribute)
    input.placeholder = placeholder
    input.type = 'text'
    input.classList.add('form-input-base')
    input.addEventListener('focus', function () {
        this.select();
    });

    wrap.appendChild(input)

    form.appendChild(wrap)
}


/**
 * 创建下拉选择栏
 * @param {string} title //标题
 * @param {string} attribute //属性名
 * @param {Array} selectArr //选项的内容 
 * @param {boolean} isRequired //是否为必填项
 */
function createSelect(title, attribute, selectArr, isRequired) {
    let form = document.getElementById('form')
    let wrap = document.createElement('div')
    wrap.classList.add('form-item-base')

    //标题
    let label = document.createElement('label')
    label.classList.add('label')
    if (isRequired) label.classList.add('required')
    label.setAttribute('for', 'select')
    let labelText = document.createTextNode(title)
    label.appendChild(labelText)

    wrap.appendChild(label)

    //下拉框
    let select = document.createElement('div')
    select.setAttribute('id', 'select' + attribute)
    select.classList.add('select')

    let input = document.createElement('input')

    input.setAttribute('id', 'selectText' + attribute)
    input.setAttribute('name', attribute)

    input.classList.add('select-choose')
    input.type = 'text'
    input.placeholder = '请选择' + title
    input.readOnly = 'readOnly'

    //下拉框状态的样式
    let selectStyle = [
        { id: 'select' + attribute, class: 'select-focus' },
        { id: 'selectText' + attribute, class: 'choose-focus' }
    ];
    let unSelectStyle = [
        { id: 'option' + attribute, class: 'hide' }
    ];

    input.onclick = () => {
        changeClass(selectStyle, unSelectStyle)
    }

    select.appendChild(input)

    let selectIcon = document.createElement('div')
    selectIcon.classList.add('select-icon')

    let icon = document.createElement('img')
    icon.src = './images/arrow.png'

    selectIcon.appendChild(icon)

    select.appendChild(selectIcon)

    //下拉框选项
    let option = document.createElement('div')
    option.setAttribute('id', 'option' + attribute)
    option.classList.add('select-option')
    option.classList.add('hide')
    let ul = document.createElement("ul");

    selectArr.forEach((element) => {
        let li = document.createElement("li");
        li.onclick = function () {
            let inputDate = document.getElementById('selectText' + attribute)
            inputDate.value = element
            changeClass(unSelectStyle, selectStyle)
        }
        let t = document.createTextNode(element)
        li.appendChild(t)
        ul.appendChild(li);
    })

    option.appendChild(ul)
    select.appendChild(option)
    wrap.appendChild(select)
    form.appendChild(wrap)
}

/**
 * 创建单选框
 * @param {string} title //标题
 * @param {string} attribute //属性名
 * @param {Array} value //属性值
 * @param {boolean} isRequired //是否必填
 */
function createRdaioInput(title, attribute, selectArr, isRequired) {
    let form = document.getElementById('form')
    let wrap = document.createElement('div')
    wrap.classList.add('form-item-base')

    //标题
    let label = document.createElement('label')
    label.classList.add('label')
    if (isRequired) label.classList.add('required')
    label.setAttribute('for', attribute)
    let labelText = document.createTextNode(title)
    label.appendChild(labelText)

    wrap.appendChild(label)

    let radiuContainer = document.createElement('div')
    radiuContainer.classList.add('form-input-base')

    for (let i = 0; i < selectArr.length; i++) {
        let label1 = document.createElement('label')
        label1.classList.add('radio')
        let input = document.createElement('input')
        input.setAttribute('name', attribute)
        input.setAttribute('id', attribute)
        input.type = 'radio'
        input.classList.add('form-input-radio')
        input.value = selectArr[i]
        if (!i) input.checked = true
        label1.appendChild(input)

        let label1Text = document.createTextNode(selectArr[i])
        label1.appendChild(label1Text)

        radiuContainer.appendChild(label1)
    }
    wrap.appendChild(radiuContainer)
    form.appendChild(wrap)
}

/**
 * 创建多行文本输入控件
 * @param {string} title  //标题
 * @param {string} attribute  //属性名
 * @param {string} tip   //提示信息
 * @param {boolean} isRequired //是否必填
 */
function createTextArea(title, attribute, tip, isRequired) {
    let form = document.getElementById('form')
    let wrap = document.createElement('div')
    wrap.classList.add('form-item-textarea')

    //标题
    let label = document.createElement('label')
    label.classList.add('label')
    if (isRequired) label.classList.add('required')
    label.setAttribute('for', 'textarea' + attribute)
    let labelText = document.createTextNode(title)
    label.appendChild(labelText)

    wrap.appendChild(label)

    let textArea = document.createElement('textarea')
    textArea.setAttribute('id', attribute)
    textArea.setAttribute('name', attribute)
    textArea.rows = 3
    textArea.cols = 20
    textArea.placeholder = tip
    textArea.addEventListener('focus', function () {
        this.select();
    });
    wrap.appendChild(textArea)
    form.appendChild(wrap)
}

/**
 * 创建文件上传域
 * @param {string} title //标题
 * @param {string} attribute //属性名
 * @param {number} maxNum //文件的最大数量
 * @param {boolean} isRequired //是否必填
 */
function createFileInput(title, attribute, maxNum, isRequired) {
    let form = document.getElementById('form')
    let wrap = document.createElement('div')
    wrap.classList.add('form-item-file')

    //标题
    let label = document.createElement('label')
    label.classList.add('label')
    if (isRequired) label.classList.add('required')
    let labelText = document.createTextNode(title)
    label.appendChild(labelText)

    wrap.appendChild(label)

    //文件上传框
    let uploadContainer = document.createElement('div')
    uploadContainer.classList.add('upload-container')
    uploadContainer.setAttribute('id', 'upload-container')
    let text = document.createTextNode('选择')
    uploadContainer.appendChild(text)

    let fileUrl = document.createElement('div')
    fileUrl.classList.add('file_url')

    let linkIcon = document.createElement('img')
    linkIcon.src = './images/link.png'
    fileUrl.appendChild(linkIcon)

    let p = document.createElement('P')


    p.setAttribute('id', 'file_url' + attribute)
    fileUrl.appendChild(p)

    uploadContainer.appendChild(fileUrl)

    let uploadIcon = document.createElement('img')
    uploadIcon.src = './images/upload.png'

    uploadContainer.appendChild(uploadIcon)

    let fileInput = document.createElement('input')
    fileInput.type = 'file'
    fileInput.onchange = () => {
        showFileName(attribute, maxNum)
    }

    fileInput.setAttribute('id', attribute)
    fileInput.setAttribute('name', attribute)
    fileInput.classList.add('upload')
    fileInput.setAttribute("multiple", "multiple")

    uploadContainer.appendChild(fileInput)
    wrap.appendChild(uploadContainer)
    form.appendChild(wrap)
}


/**
 * 创建表单的提交按钮
 * @param {string} value //按钮的标题
 */
function createSubmit(value) {
    let form = document.getElementById('form')
    let input = document.createElement('input')
    input.type = 'button'
    input.value = value
    input.onclick = () => {
        checkForm()
    }
    input.classList.add('submit')
    form.appendChild(input)
}

/**
 * 显示选择的文件名称
 * @param {string} attribute //要操作的属性名
 * @param {number} maxNum //最大文件数
 */
function showFileName(attribute, maxNum) {

    let filename = document.getElementById(attribute);

    if (filename.files[0] == undefined) {
        console.log('未选择文件！');
    }
    else {
        if (filename.files.length > maxNum) {
            showMessage('最多只能选择' + maxNum + '个文件', 'error')
        } else {
            if (filename.files.length > 1) {
                if (filename.files[0].name.length > 5) {
                    document.getElementById('file_url' + attribute).innerHTML = filename.files[0].name.substring(0, 5) + '...等' + filename.files.length + '个文件'
                } else {
                    document.getElementById('file_url' + attribute).innerHTML = filename.files[0].name + '等' + filename.files.length + '个文件'
                }
            } else {
                document.getElementById('file_url' + attribute).innerHTML = filename.files[0].name;
            }

            //TODO 文件保存

        }
    }
}

/**
 * 弹框提示
 * @param {string} msg  //消息内容
 * @param {string} type //消息类型
 */
function showMessage(msg, type) {
    let container = document.getElementById('container')
    let Message = document.createElement('div')
    Message.classList.add('message')
    if (msg.length < 10) Message.classList.add('small')
    else Message.classList.add('big')
    Message.setAttribute('id', 'msg')

    let msgIcon = document.createElement('div')
    msgIcon.classList.add('msg-icon`')

    let img = document.createElement('img')
    img.src = './images/' + type + '.png'
    msgIcon.appendChild(img)

    Message.appendChild(msgIcon)

    let content = document.createElement('div')
    let text = document.createTextNode(msg)
    content.appendChild(text)
    content.classList.add('msg-content')
    Message.appendChild(content)

    container.appendChild(Message)

    let count = (function () {
        let timer;
        let i = 0;
        function change(tar) {
            i++;
            let num = 1 - i / 100;
            if (num < 0.7) Message.style.top = num * 400 + 'px'
            Message.style.opacity = num;
            if (i === tar) {
                clearTimeout(timer);
                return false;
            }
            timer = setTimeout(function () {
                change(tar)
            }, 30)
        }
        return change;
    })()

    setTimeout(() => {
        count(100)

    }, 2000)
    setTimeout(() => {
        container.removeChild(Message)

    }, 5000)

}

/**
 * 创建图像上传域
 * @param {string} title //标题
 * @param {string} attribute //属性名
 * @param {number} maxNum //文件的最大数量
 * @param {boolean} isRequired //是否必填
 */
function createImageInput(title, attribute, maxNum, isRequired) {
    if (imgNum > maxNum) {
        showMessage('最多选择' + maxNum + '张图片', 'prompt')
        return;
    }
    let form = document.getElementById('form')
    //标题
    let label = document.createElement('label')
    label.classList.add('label')
    if (isRequired) label.classList.add('required')
    let labelText = document.createTextNode(title)
    label.appendChild(labelText)
    form.appendChild(label)

    let wrap = document.createElement('div')
    wrap.classList.add('form-input-img')
    wrap.setAttribute('id', 'imgList-' + attribute)
    //文件上传框
    let uploadContainer = document.createElement('div')
    uploadContainer.classList.add('input-img-container')
    let input = document.createElement('input')
    input.classList.add('upload')
    input.setAttribute('multiple', 'multiple')
    input.type = 'file'
    input.setAttribute('name', 'input-' + attribute)
    input.setAttribute('id', 'input-' + attribute)
    input.setAttribute('accept', "image/*")
    input.onchange = (e) => {
        imgPreview(attribute, e.target, maxNum)
    }
    uploadContainer.appendChild(input)
    wrap.appendChild(uploadContainer)
    form.appendChild(wrap)
}

/**
 * 图片预览
 * @param {object} fileDom 
 * @param {string} id 
 * @param {number} maxNum 
 * @returns 
 */
function imgPreview(attribute, fileDom, maxNum) {
    console.log("fileDom", "success")
    //判断是否支持FileReader
    var imgList = document.getElementsByName('preview-img-' + attribute);

    // fileDom.files.forEach(file => {
    if (fileDom.files.length + imgList.length > maxNum) {
        showMessage('最多选择' + maxNum + '张图片', 'prompt')
        return
    }
    for (let i = 0; i < fileDom.files.length; i++) {
        if (window.FileReader) {
            var reader = new FileReader();
        } else {
            showMessage("您的设备不支持图片预览功能，如需该功能请升级您的设备！", "warning");
            return
        }
        var file = fileDom.files[i];
        var imageType = /^image\//;
        //是否是图片
        if (!imageType.test(file.type)) {
            showMessage("请选择图片！", "warning");
            return;
        }
        //读取完成
        reader.onload = function (e) {
            let imgList = document.getElementById('imgList-' + attribute)
            let imgContainer = document.createElement('div')
            imgContainer.classList.add('img-container')
            let img = document.createElement("img");
            img.setAttribute('id', 'preview-img-' + attribute)
            img.setAttribute('name', 'preview-img-' + attribute)
            img.src = e.target.result;
            imgContainer.appendChild(img)
            imgContainer.setAttribute('id', 'preview-' + attribute + (++imgNum))

            let imgDel = document.createElement('div')
            imgDel.classList.add('img-del')
            imgDel.onclick = () => {
                imgList.removeChild(imgContainer)
            }
            let delIcon = document.createElement('img')
            delIcon.src = './images/del.png'
            imgDel.appendChild(delIcon)
            imgContainer.appendChild(imgDel)
            imgList.insertBefore(imgContainer, imgList.children[imgList.children.length - 1])
        };
        reader.readAsDataURL(file);
    }
}

/**
 * 将base64转回图片
 * @param {*} urlData 
 * @param {*} type 
 * @returns 
 */
function base64ToBlob(urlData, type) {
    let arr = urlData.split(',');
    let mime = arr[0].match(/:(.*?);/)[1] || type;
    // 去掉url的头，并转化为byte
    let bytes = window.atob(arr[1]);
    // 处理异常,将ascii码小于0的转换为大于0
    let ab = new ArrayBuffer(bytes.length);
    // 生成视图（直接针对内存）：8位无符号整数，长度1个字节
    let ia = new Uint8Array(ab);
    for (let i = 0; i < bytes.length; i++) {
        ia[i] = bytes.charCodeAt(i);
    }
    return new Blob([ab], {
        type: mime
    });
}